package com.example.everying.utils;

import com.github.houbb.sensitive.word.exception.SensitiveWordException;
import lombok.Data;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理类
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    // 添加统一的日志记录方法
    private void logException(String type, Exception e, String customMessage) {
        String stackTrace = ExceptionUtils.getStackTrace(e);
        String errorMessage = String.format("%s - 类型: %s, 消息: %s, 堆栈: %s",
                customMessage, e.getClass().getName(), e.getMessage(), stackTrace);
        log.error(errorMessage);
    }

    @ExceptionHandler(DataIntegrityViolationException.class)
    @ResponseBody
    public Result handleDataIntegrityViolationException(DataIntegrityViolationException e) {
        // 获取详细的错误信息
        String errorMessage = getDetailedErrorMessage(e);

        // 记录详细的错误日志
        log.error("数据完整性违反异常: {}\n异常堆栈: {}", errorMessage, ExceptionUtils.getStackTrace(e));

        return Result.fail("数据保存失败：" + errorMessage);
    }

    private String getDetailedErrorMessage(DataIntegrityViolationException e) {
        if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
            SQLIntegrityConstraintViolationException sqlEx = (SQLIntegrityConstraintViolationException) e.getCause();
            return String.format("字段约束错误：%s", sqlEx.getMessage());
        }
        return e.getMessage();
    }

    /**
     * 处理方法参数校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String message = extractDefaultMessage(e.getMessage());
        logException("参数校验失败", e, message);
        return Result.fail(message);
    }

    /**
     * 处理Bind异常
     */
    @ExceptionHandler(BindException.class)
    public Result<String> handleBindException(BindException e) {
        String message = extractDefaultMessage(e.getMessage());
        logException("数据绑定异常", e, message);
        return Result.fail(message);
    }

    /**
     * 处理JSON解析异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logException("JSON解析异常", e, "请求数据格式错误");
        return Result.fail("无效的JSON格式");
    }

    /**
     * 处理自定义校园异常
     */
    @ExceptionHandler(CampusException.class)
    public Result<String> handleCampusException(CampusException e) {
        logException("业务异常", e, e.getMessage());
        return Result.build(e.getCode(), e.getMessage());
    }

    /**
     * 处理敏感词异常
     */
    @ExceptionHandler(SensitiveWordException.class)
    public Result<String> handleSensitiveWordException(SensitiveWordException e) {
        logException("敏感词异常", e, e.getMessage());
        return Result.fail(201, e.getMessage());
    }

    /**
     * 处理通用异常（作为最后兜底）
     */
    @ExceptionHandler(Exception.class)
    public Result<String> handleException(Exception e) {
        e.printStackTrace(); // 生产环境建议使用日志记录
        logException("网络错误", e, e.getMessage());
        return Result.fail("网络错误");
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result<String> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        String message = "aaaaaaaaa";
        return Result.fail(message);
    }

    /**
     * 从异常信息中提取默认消息
     */
    private String extractDefaultMessage(String message) {
        if (message == null) return "参数验证失败";
        String extracted = StringUtils.substringAfterLast(message, "default message");
        if (extracted != null) {
            extracted = extracted.replace("]]", "]").trim();
            if (!extracted.isEmpty()) return extracted;
        }
        return "参数验证失败";
    }


}
